package handler

import (
	"github.com/gccai/write_helper/enum"
	"github.com/gccai/write_helper/model"
	"github.com/gccai/write_helper/resp"
	"github.com/gccai/write_helper/service"
	"github.com/gccai/write_helper/utils"
	"github.com/gin-gonic/gin"
	"net/http"
)

type ChapterHandler struct {
	ChapterSrc service.ChapterServiceInterface
	Booksrc    service.BookSrvInterface
}

type ChapterHandlerInterface interface {
	GetEntity(res model.Chapter) resp.Chapter
	ChapterListHandler(ctx *gin.Context)
	ChapterInfoHandler(ctx *gin.Context)
	AddChapterHandler(ctx *gin.Context)
	EditChapterHandler(ctx *gin.Context)
	DeleteBookHandler(ctx *gin.Context)
}

func (c ChapterHandler) GetEntity(res model.Chapter) resp.Chapter {
	return resp.Chapter{
		UserId:           res.UserId,
		ChapterId:        res.ChapterId,
		BookName:         res.BookName,
		ChapterName:      res.ChapterName,
		ChapterStoryCore: res.ChapterStoryCore,
		ChapterContent:   res.ChapterContent,
		CreateAt:         res.CreateAt,
		DeleteAt:         res.DeleteAt,
		IsDeleted:        res.IsDeleted,
	}
}

//http://localhost:8888/api/chapter/list?userId=?&&bookName=? ---> 章节数+{num,chaptername}
func (c ChapterHandler) ChapterListHandler(ctx *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	var chapter model.Chapter
	err := ctx.ShouldBindQuery(&chapter)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}

	chapters, err := c.ChapterSrc.GetChapters(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}

	var newList []interface{}
	var chapterNameAndNum resp.ChapterNameAndNumber

	for _, chapter := range chapters {
		num, err := utils.GetNum(chapter.ChapterId)
		if err != nil {
			entity.Msg = err.Error()
			ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
			return
		}
		chapterNameAndNum.Num = num
		chapterNameAndNum.ChapterName = chapter.ChapterName
		newList = append(newList, chapterNameAndNum)
	}
	chapterCount, err := c.ChapterSrc.GetChapterCount(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Data = newList
	entity.Total = int(chapterCount)
	ctx.JSON(http.StatusOK, gin.H{"entity": entity})
}

//http://localhost:8888/api/chapter/:userId/:bookName/:chapterId
func (c ChapterHandler) ChapterInfoHandler(ctx *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	var chapter model.Chapter
	userId := ctx.Param("userId")
	bookName := ctx.Param("bookName")
	chapterId := ctx.Param("chapterId")
	chapter.UserId = userId
	chapter.BookName = bookName
	chapter.ChapterId = chapterId

	res, err := c.ChapterSrc.GetChapterContent(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}

	entity.Code = int(enum.OperateOk)
	entity.Msg = enum.OperateOk.String()
	entity.Data = *res
	ctx.JSON(http.StatusOK, gin.H{"entity": entity})
}

// http://localhost:8888/api/chapter/add
func (c ChapterHandler) AddChapterHandler(ctx *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	var book model.Book
	var chapter model.Chapter
	err := ctx.ShouldBindJSON(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	// 需要更改book表中，对应表的chaptercount字段。
	chapterNums, err := c.ChapterSrc.GetChapterCount(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	} else {
		book.ChapterCount = chapterNums
		book.UserId = chapter.UserId
		book.BookName = chapter.BookName
	}
	res := c.Booksrc.UpdateChapter(&book)
	if !res {
		entity.Msg = "更新章节数目失败"
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	// 正常的添加chapter表。
	chapterPointerRes, err := c.ChapterSrc.Add(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = "ok"
	entity.Data = *chapterPointerRes
	ctx.JSON(http.StatusOK, gin.H{"entity": entity})
}

//http://localhost:8888/api/chapter/edit
func (c ChapterHandler) EditChapterHandler(ctx *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateOk),
		Msg:  enum.OperateOk.String(),
		Data: nil,
	}
	var chapter model.Chapter
	err := ctx.ShouldBindJSON(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	res := c.ChapterSrc.Edit(&chapter)
	if res == nil {
		entity.Msg = "更新出现问题"
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = "ok"
	entity.Data = *res
	ctx.JSON(http.StatusOK, gin.H{"entity": entity})
}

// http://localhost:8888/api/chapter/delete/:userId/:bookName/:chapterId
func (c ChapterHandler) DeleteBookHandler(ctx *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateOk),
		Msg:  enum.OperateOk.String(),
		Data: nil,
	}
	chapterId := ctx.Param("chapterId")
	userId := ctx.Param("userId")
	bookName := ctx.Param("bookName")
	var chapter model.Chapter
	chapter.ChapterId = chapterId
	chapter.BookName = bookName
	chapter.UserId = userId

	_, err := c.ChapterSrc.Delete(&chapter)
	if err != nil {
		entity.Msg = err.Error()
		ctx.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = enum.OperateOk.String()
	ctx.JSON(http.StatusOK, gin.H{"entity": entity})
}
